/*
 * @Description: In User Settings Edit
 * @Author: your name
 * @Date: 2019-09-12 11:44:54
 * @LastEditTime : 2019-12-20 14:36:22
 * @LastEditors  : Please set LastEditors
 */
/**
 * Created by jiachenpan on 16/11/18.
 */

import { groupBy } from 'lodash';
import { TreeUtil } from './treeUtil';

export function parseTime(time, cFormat) {
  if (arguments.length === 0) {
    return null;
  }
  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}';
  let date;
  if (typeof time === 'object') {
    date = time;
  } else {
    if (('' + time).length === 10) time = parseInt(time) * 1000;
    date = new Date(time);
  }
  const formatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay(),
  };
  const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
    let value = formatObj[key];
    // Note: getDay() returns 0 on Sunday
    if (key === 'a') {
      return ['日', '一', '二', '三', '四', '五', '六'][value];
    }
    if (result.length > 0 && value < 10) {
      value = '0' + value;
    }
    return value || 0;
  });
  return time_str;
}

export function formatTime(time, option) {
  time = +time * 1000;
  const d = new Date(time);
  const now = Date.now();

  const diff = (now - d) / 1000;

  if (diff < 30) {
    return '刚刚';
  } else if (diff < 3600) {
    // less 1 hour
    return Math.ceil(diff / 60) + '分钟前';
  } else if (diff < 3600 * 24) {
    return Math.ceil(diff / 3600) + '小时前';
  } else if (diff < 3600 * 24 * 2) {
    return '1天前';
  }
  if (option) {
    return parseTime(time, option);
  } else {
    return (
      d.getMonth() +
      1 +
      '月' +
      d.getDate() +
      '日' +
      d.getHours() +
      '时' +
      d.getMinutes() +
      '分'
    );
  }
}

// 格式化时间
export function getQueryObject(url) {
  url = url == null ? window.location.href : url;
  const search = url.substring(url.lastIndexOf('?') + 1);
  const obj = {};
  const reg = /([^?&=]+)=([^?&=]*)/g;
  search.replace(reg, (rs, $1, $2) => {
    const name = decodeURIComponent($1);
    let val = decodeURIComponent($2);
    val = String(val);
    obj[name] = val;
    return rs;
  });
  return obj;
}

/**
 *get getByteLen
 * @param {Sting} val input value
 * @returns {number} output value
 */
export function getByteLen(val) {
  let len = 0;
  for (let i = 0; i < val.length; i++) {
    if (val[i].match(/[^\x00-\xff]/gi) != null) {
      len += 1;
    } else {
      len += 0.5;
    }
  }
  return Math.floor(len);
}

export function cleanArray(actual) {
  const newArray = [];
  for (let i = 0; i < actual.length; i++) {
    if (actual[i]) {
      newArray.push(actual[i]);
    }
  }
  return newArray;
}

export function param(json) {
  if (!json) return '';
  return cleanArray(
    Object.keys(json).map(key => {
      if (json[key] === undefined) return '';
      return encodeURIComponent(key) + '=' + encodeURIComponent(json[key]);
    }),
  ).join('&');
}

export function param2Obj(url) {
  const search = url.split('?')[1];
  if (!search) {
    return {};
  }
  return JSON.parse(
    '{"' +
      decodeURIComponent(search)
        .replace(/"/g, '\\"')
        .replace(/&/g, '","')
        .replace(/=/g, '":"') +
      '"}',
  );
}

export function html2Text(val) {
  const div = document.createElement('div');
  div.innerHTML = val;
  return div.textContent || div.innerText;
}

export function objectMerge(target, source) {
  /* Merges two  objects,
     giving the last one precedence */

  if (typeof target !== 'object') {
    target = {};
  }
  if (Array.isArray(source)) {
    return source.slice();
  }
  Object.keys(source).forEach(property => {
    const sourceProperty = source[property];
    if (typeof sourceProperty === 'object') {
      target[property] = objectMerge(target[property], sourceProperty);
    } else {
      target[property] = sourceProperty;
    }
  });
  return target;
}

export function toggleClass(element, className) {
  if (!element || !className) {
    return;
  }
  let classString = element.className;
  const nameIndex = classString.indexOf(className);
  if (nameIndex === -1) {
    classString += '' + className;
  } else {
    classString =
      classString.substr(0, nameIndex) +
      classString.substr(nameIndex + className.length);
  }
  element.className = classString;
}

export const pickerOptions = [
  {
    text: '今天',
    onClick(picker) {
      const end = new Date();
      const start = new Date(new Date().toDateString());
      end.setTime(start.getTime());
      picker.$emit('pick', [start, end]);
    },
  },
  {
    text: '最近一周',
    onClick(picker) {
      const end = new Date(new Date().toDateString());
      const start = new Date();
      start.setTime(end.getTime() - 3600 * 1000 * 24 * 7);
      picker.$emit('pick', [start, end]);
    },
  },
  {
    text: '最近一个月',
    onClick(picker) {
      const end = new Date(new Date().toDateString());
      const start = new Date();
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
      picker.$emit('pick', [start, end]);
    },
  },
  {
    text: '最近三个月',
    onClick(picker) {
      const end = new Date(new Date().toDateString());
      const start = new Date();
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
      picker.$emit('pick', [start, end]);
    },
  },
];

export function getTime(type) {
  if (type === 'start') {
    return new Date().getTime() - 3600 * 1000 * 24 * 90;
  } else {
    return new Date(new Date().toDateString());
  }
}

export function debounce(func, wait, immediate) {
  let timeout, args, context, timestamp, result;

  const later = function() {
    // 据上一次触发时间间隔
    const last = +new Date() - timestamp;

    // 上次被包装函数被调用时间间隔last小于设定时间间隔wait
    if (last < wait && last > 0) {
      timeout = setTimeout(later, wait - last);
    } else {
      timeout = null;
      // 如果设定为immediate===true，因为开始边界已经调用过了此处无需调用
      if (!immediate) {
        result = func.apply(context, args);
        if (!timeout) context = args = null;
      }
    }
  };

  return function(...args) {
    context = this;
    timestamp = +new Date();
    const callNow = immediate && !timeout;
    // 如果延时不存在，重新设定延时
    if (!timeout) timeout = setTimeout(later, wait);
    if (callNow) {
      result = func.apply(context, args);
      context = args = null;
    }

    return result;
  };
}

/**
 * This is just a simple version of deep copy
 * Has a lot of edge cases bug
 * If you want to use a perfect deep copy, use lodash's _.cloneDeep
 */
export function deepClone(source) {
  if (!source && typeof source !== 'object') {
    throw new Error('error arguments', 'shallowClone');
  }
  const targetObj = source.constructor === Array ? [] : {};
  Object.keys(source).forEach(keys => {
    if (source[keys] && typeof source[keys] === 'object') {
      targetObj[keys] = deepClone(source[keys]);
    } else {
      targetObj[keys] = source[keys];
    }
  });
  return targetObj;
}

export function uniqueArr(arr) {
  return Array.from(new Set(arr));
}

export function isExternal(path) {
  return /^(https?:|mailto:|tel:)/.test(path);
}

function clone(obj, except) {
  var newObj = {},
    self = obj;
  for (var i in self) {
    if (i !== except) {
      newObj[i] = self[i];
    }
  }
  return newObj;
}
// 树转平滑数组
export function getPlainNode(nodeList) {
  let stack = nodeList.concat(),
    data = [];
  while (stack.length != 0) {
    let pop = stack.pop();
    data.push(clone(pop, 'children'));
    let children = pop.children;
    if (children) {
      for (let i = children.length - 1; i >= 0; i--) {
        children[i] = { ...children[i], ...{ __isChildren: true } };
        stack.push(children[i]);
      }
    }
  }
  return data;
}

/**
 *
 *   数组转树对象
 *
 *   参数
 *   Array data: 一组数组数据
 *   Object options: 一个包含以下字段的对象:
 *   id (String): 唯一的节点标识. 默认: 'id'
 *   pid (String): 父节点id，可根据此id找到父节点. 默认: 'pid'
 *   children (String): 子节点名称. 默认: 'children'  - firstPid (String):根节点父id . 默认: null
 *
 *   返回值
 *   Array: 转换后的结果
 *
 */
export function arrayToTree(array, options) {
  options = Object.assign(
    {
      id: 'id',
      pid: 'pid',
      children: 'children',
      firstPid: null,
    },
    options,
  );
  const groupArray = groupBy(array, function(n) {
    return n[options.pid];
  });
  const firstArray = groupArray[options.firstPid];
  transform(firstArray);
  function transform(startList) {
    if (startList)
      for (let i = 0; i < startList.length; i++) {
        groupArray[startList[i][options.id]] &&
          (startList[i][options.children] =
            groupArray[startList[i][options.id]]);
        transform(startList[i][options.children]);
      }
  }

  return firstArray !== undefined ? firstArray : array;
}

/**
 *
 *  替换对象的key
 *  obj      Object|Array<Object>   要替换key的对象/或对象数组
 *  search   Array<string>   要搜索key数组
 *  replace  Array<string>   要替换成key数组
 *
 * */
export function keyReplace(obj, search, replace) {
  let ret;

  if (typeof obj !== 'object') {
    throw new TypeError('Expected an object');
  }

  if (Array.isArray(obj)) {
    ret = [];
    obj.forEach(function(el) {
      ret.push(replaceKey(el));
    });
  } else {
    ret = replaceKey(obj);
  }

  function replaceKey(_obj) {
    const ret = {};
    Object.keys(_obj).forEach(el => {
      search.forEach((str, index) => {
        ret[el.replace(str, replace[index])] = _obj[el];
      });
    });
    return ret;
  }

  return ret;
}

// 获取拆分的树结构
export function getRootsAndFlatData(sourceData) {
  // // 拷贝一份数据源
  let _copyData = JSON.parse(JSON.stringify(sourceData));

  // // 数据源转平滑数组
  let __flatData = [],
    roots = [];
  TreeUtil.forEachNodes(_copyData, node => {
    // 如果包含子节点children.length > 0
    if (node.children && node.children.length > 0) {
      node.hasChildren = true;
      node.children.forEach(child => {
        child.parentId = node.id;
      });
    }
    // 移除节点中的children属性
    node = _.omit(node, ['children']);
    // 保存变更后的节点
    __flatData.push(node);

    // 获取第一层级数据
    if (node.parentId === '-1') {
      roots.push(node);
    }
  });

  console.log(__flatData, '平滑数组~~~');
  return {
    roots: roots,
    flatData: __flatData,
  };
}
// 查找归属当前节点的子节点数组
export function getNodeChildren(data, id) {
  let children = [];
  data.forEach(node => {
    if (node.parentId === id) {
      children.push(node);
    }
  });
  return children;
}

/**
 *
 *  通过 JSON 对象实现深拷贝
 *  obj      Object|Array<Object>   要深拷贝的对象/或对象数组
 *
 * */
/*function deepClone(obj) {
  let _obj = JSON.stringify(obj),
    objClone = JSON.parse(_obj);
  return objClone;
}*/

/**
 *
 *  替换代理路径
 *
 */
export function replaceProxyPath(path) {
  if (process.env.BASE_API && process.env.BASE_API !== '') {
    return process.env.BASE_API + path;
  } else {
    return path.substring(path.length, 1);
  }
}

/**
 *
 *  判断选中的节点是不是单项工程
 *
 */
export function isGroup(array, id) {
  let result = false;
  let getArr = getPlainNode(array);
  getArr.forEach(item => {
    if (item.id == id) {
      if (item.kind == 'Group') {
        result = true;
      }
    }
  });
  return result;
}

/**
 *
 *  获取parentId
 *
 */
export function getParentId(array, id) {
  let result = '';
  let getArr = getPlainNode(array);
  getArr.forEach(item => {
    if (item.id == id) {
      result = item.parentId;
    }
  });
  return result;
}

/**
 * 数字转中文
 */
export function toChinesNum(num) {
  let changeNum = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']; //changeNum[0] = "零"
  let unit = ['', '十', '百', '千', '万'];
  num = parseInt(num);
  let getWan = temp => {
    let strArr = temp
      .toString()
      .split('')
      .reverse();
    let newNum = '';
    for (var i = 0; i < strArr.length; i++) {
      newNum =
        (i == 0 && strArr[i] == 0
          ? ''
          : i > 0 && strArr[i] == 0 && strArr[i - 1] == 0
          ? ''
          : changeNum[strArr[i]] + (strArr[i] == 0 ? unit[0] : unit[i])) +
        newNum;
    }
    return newNum;
  };
  let overWan = Math.floor(num / 10000);
  let noWan = num % 10000;
  if (noWan.toString().length < 4) noWan = '0' + noWan;
  return overWan ? getWan(overWan) + '万' + getWan(noWan) : getWan(num);
}

/**
 * 模仿PHP的strtotime()函数
 * strtotime('2012-07-27 12:43:43') OR strtotime('2012-07-27')
 * @return 时间戳
 */
export function strtotime(str) {
  var _arr = str.split(' ');
  var _day = _arr[0].split('-');
  _arr[1] = _arr[1] == null ? '0:0:0' : _arr[1];
  var _time = _arr[1].split(':');
  for (var i = _day.length - 1; i >= 0; i--) {
    _day[i] = isNaN(parseInt(_day[i])) ? 0 : parseInt(_day[i]);
  }
  for (var i = _time.length - 1; i >= 0; i--) {
    _time[i] = isNaN(parseInt(_time[i])) ? 0 : parseInt(_time[i]);
  }
  var _temp = new Date(
    _day[0],
    _day[1] - 1,
    _day[2],
    _time[0],
    _time[1],
    _time[2],
  );
  return _temp.getTime() / 1000;
}

/**
 * 计算不固定列的宽度
 */
export function calculateColumnsWidth(columns) {
  let columnsWidth = 0;
  columns.forEach(c => {
    columnsWidth += c.width;
  });
  return columnsWidth + 10;
}

export function toFixed2(number, length) {
  if (number || number == 0) {
    if (!length) length = 2;
    number = number.toFixed(length);
  }
  return number;
}

export function toFixed3(number, length) {
  if (number) {
    if (!length) length = 2;
    return number.toFixed(length);
  }
  return '';
}

export function parseNumber(text) {
  if (text == 0) {
    text = '';
  }
  return text;
}

// 过滤时间 2019-12-20 12:00 | 2019-12-20
export function fitlerDate(date, n) {
  var newDate = /\d{4}-\d{1,2}-\d{1,2}/g.exec(date);
  return newDate[0];
  // console.log(newDate,'====newDate',newDate)
}

//判断是否是数字
export function isNumber(val) {
  var regPos = /^\d+(\.\d+)?$/; //非负浮点数
  var regNeg = /^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$/; //负浮点数
  if (regPos.test(val) || regNeg.test(val)) {
    return true;
  } else {
    return false;
  }
}

//前端生成id
export function generateUUID() {
  var d = new Date().getTime();
  if (window.performance && typeof window.performance.now === 'function') {
    d += performance.now(); //use high-precision timer if available
  }
  var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(
    c,
  ) {
    var r = (d + Math.random() * 16) % 16 | 0;
    d = Math.floor(d / 16);
    return (c == 'x' ? r : (r & 0x3) | 0x8).toString(16);
  });
  return uuid;
}

//根据id在树里面获取对应的节点
export function getTreeNode(arr, id) {
  let result = null;
  let array = getPlainNode(arr);
  array.forEach(item => {
    if (item.id == id) {
      result = item;
    }
  });
  return result;
}
//根据id在树里面获取对应的节点
export function getUTreeNode(arr, id) {
  let result = null;
  TreeUtil.forEachNodes(arr, item => {
    if (item.id == id) {
      result = item;
    }
  });
  return result;
}

//根据id获取对应的对应节点的上一级和下一级的sort字段
export function getNodeAndParentIndex(json, nodeId) {
  let lastOrder = null;
  let nextOrder = null;
  let targetArr = null;

  get(json);
  //递归节点数，获取节点所在的数组，和对应的索引
  function get(array) {
    for (let i = 0; i < array.length; i++) {
      if (array[i].children) {
        if (nodeId == array[i].id) {
          let index = array.indexOf(array[i]);
          targetArr = array;
          getSort(targetArr, index);
        }
        get(array[i].children);
      } else {
        if (nodeId == array[i].id) {
          let index = array.indexOf(array[i]);
          targetArr = array;
          getSort(targetArr, index);
        }
      }
    }
  }

  function getSort(arr, index) {
    console.log(arr, index);
    if (index == 0) {
      lastOrder = -1;
      nextOrder = arr[index + 1].sort;
    } else if (index + 1 == arr.length) {
      lastOrder = arr[index - 1].sort;
      nextOrder = -1;
    } else {
      lastOrder = arr[index - 1].sort;
      nextOrder = arr[index + 1].sort;
    }
  }

  return {
    lastOrder: lastOrder,
    nextOrder: nextOrder,
  };
}

//数组去重
export function unique(arr) {
  var result = [];
  var obj = {};
  for (var i = 0; i < arr.length; i++) {
    if (!obj[arr[i].id]) {
      result.push(arr[i]);
      obj[arr[i].id] = true;
    }
  }
  return result;
}
/*function uniqueArr(arr) {
  return Array.from(new Set(arr));
}*/

//删除json树对应的节点
export function deletJsonTreeNode(json, nodeId) {
  get(json);
  //递归节点数，获取节点所在的数组，和对应的索引
  function get(array) {
    for (let i = 0; i < array.length; i++) {
      if (array[i].children) {
        if (nodeId == array[i].id) {
          array.splice(i, 1);
        }
        get(array[i].children);
      } else {
        if (nodeId == array[i].id) {
          array.splice(i, 1);
        }
      }
    }
  }
}

/**
 * 根据NodeID查找当前节点的父节点
 *
 * @param  {[type]}
 * @param  {[type]}
 */
export function getParentNode(json, nodeId) {
  return new Promise((resolve, reject) => {
    console.log(json);
    let parentNode = null;
    let parentList = [];
    let node = null;
    let index = 0;

    getNode(json, nodeId);
    function getNode(json, nodeId, cb) {
      //1.第一层 root 深度遍历整个JSON
      for (var i = 0; i < json.length; i++) {
        if (node) {
          break;
        }
        var obj = json[i];
        //没有就下一个
        if (!obj || !obj.id) {
          continue;
        }
        if (obj.children) {
          //4.递归前，记录当前节点，作为parent 父亲
          parentNode = obj;
          parentList.push(obj);
          if (obj.id == nodeId) {
            //找到了与nodeId匹配的节点，结束递归
            node = obj;
            index = i - 1;
            break;
          }
          //递归往下找
          getNode(obj.children, nodeId);
        } else {
          //跳出当前递归，返回上层递归
          continue;
        }
      }
    }
    window.setTimeout(() => {
      if (parentList.length > 0) {
        parentList.forEach(item => {
          if (item.children) {
            item.children.forEach(item1 => {
              if (item1.id == nodeId) {
                console.log(item1);
                console.log(item);
                parentNode = item;
                //6.返回结果obj
                resolve({
                  parentNode: parentNode,
                });
              }
            });
          }
        });
      }
    }, 200);
  });
}

/**
 * 根據URL獲取參數返回對象
 *
 * @param  {[type]}
 * @param  {[type]}
 */
export function GetRequest(urlStr) {
  if (typeof urlStr == 'undefined') {
    var url = decodeURI(location.search); //获取url中"?"符后的字符串
  } else {
    var url = '?' + urlStr.split('?')[1];
  }
  var theRequest = new Object();
  if (url.indexOf('?') != -1) {
    var str = url.substr(1);
    let strs = str.split('&');
    for (var i = 0; i < strs.length; i++) {
      theRequest[strs[i].split('=')[0]] = decodeURI(strs[i].split('=')[1]);
    }
  }
  return theRequest;
}

export function getFileNameAndType(text) {
  //截取文件名格式（333.pdf）
  var fileExtension = text.substring(text.lastIndexOf('.') + 1); //截取文件后缀名
  var pattern = /\.{1}[a-z]{1,}$/;
  if (pattern.exec(text) !== null) {
    return {
      name: text.slice(0, pattern.exec(text).index),
      type: fileExtension,
    };
  } else {
    return { name: text, type: fileExtension };
  }
}

/**
 * 数字转整数 如 100000 转为10万
 * @param {需要转化的数} num
 * @param {需要保留的小数位数} point
 */
export function tranNumber(num, point) {
  let numStr = num.toString();
  // 十万以内直接返回
  if (numStr.length < 6) {
    return numStr;
  }
  //大于8位数是亿
  else if (numStr.length > 8) {
    let decimal = numStr.substring(
      numStr.length - 8,
      numStr.length - 8 + point,
    );
    return parseFloat(parseInt(num / 100000000) + '.' + decimal) + '亿';
  }
  //大于6位数是十万 (以10W分割 10W以下全部显示)
  else if (numStr.length > 5) {
    let decimal = numStr.substring(
      numStr.length - 4,
      numStr.length - 4 + point,
    );
    return parseFloat(parseInt(num / 10000) + '.' + decimal) + '万';
  }
}

export function pad(number) {
  return ('0' + number).slice(-2);
}

export function getDuration(duration) {
  var minutes = Math.floor(duration / 1000 / 60);
  var second = Math.floor(duration / 1000 - minutes * 60);

  return `${pad(minutes)}:${pad(second)}`;
}

export const isPC = () => {
  var userAgentInfo = navigator.userAgent;
  var Agents = [
    'Android',
    'iPhone',
    'SymbianOS',
    'Windows Phone',
    'iPad',
    'iPod',
  ];
  var flag = true;
  for (var v = 0; v < Agents.length; v++) {
    if (userAgentInfo.indexOf(Agents[v]) > 0) {
      flag = false;
      break;
    }
  }
  return flag;
};
